#ifndef SERIALPORTCONTROLLER_H
#define SERIALPORTCONTROLLER_H

#include <QObject>
#include <QStringList>
#include <QSerialPort>
#include <QTimer>

class ProtocolHandler;
class CommunicationLogger;

// Module ID mapping structure
struct ModuleInfo {
    quint8 id;
    QString name;
};

// Module ID definitions with Chinese names
static const QList<ModuleInfo> MODULE_LIST = {
    {0x02, "主激光准直调焦"},
    {0x03, "525准直调焦"},
    {0x07, "方位紧锁"},
    {0x08, "俯仰紧锁"},
    {0x0A, "粗跟踪罩"},
    {0x0C, "可见光相机光阑调节"},
    {0x0D, "可见光相机调焦"},
    {0x0E, "红外相机调焦"},
    {0x0F, "精跟调焦"},
    {0x10, "照明调焦"},
    {0x11, "滤光片切换1"},
    {0x12, "滤光片切换2"},
    {0x13, "发射开罩"},
    {0x15, "截至板切换"},
    {0x16, "精相机甲滤光轮切换"},
    {0x17, "精相机乙滤光轮切换"},
    {0x18, "发射调焦"}
};

class SerialPortController : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QStringList availablePorts READ availablePorts NOTIFY availablePortsChanged)
    Q_PROPERTY(QString currentPort READ currentPort WRITE setCurrentPort NOTIFY currentPortChanged)
    Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged)
    Q_PROPERTY(quint8 targetModuleId READ targetModuleId WRITE setTargetModuleId NOTIFY targetModuleIdChanged)
    Q_PROPERTY(QString workStatus READ workStatus NOTIFY workStatusChanged)
    Q_PROPERTY(QString selfCheckStatus READ selfCheckStatus NOTIFY selfCheckStatusChanged)
    Q_PROPERTY(QString focusMode READ focusMode NOTIFY focusModeChanged)
    Q_PROPERTY(QString brakeStatus READ brakeStatus NOTIFY brakeStatusChanged)
    Q_PROPERTY(qint16 currentFocusStep READ currentFocusStep NOTIFY currentFocusStepChanged)
    Q_PROPERTY(qint16 motorTotalTravel READ motorTotalTravel NOTIFY motorTotalTravelChanged)
    Q_PROPERTY(CommunicationLogger* logger READ logger CONSTANT)
    Q_PROPERTY(qint32 baudRate READ baudRate WRITE setBaudRate NOTIFY baudRateChanged)
    Q_PROPERTY(int dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged)
    Q_PROPERTY(int parity READ parity WRITE setParity NOTIFY parityChanged)
    Q_PROPERTY(int stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged)
    Q_PROPERTY(int flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged)
    Q_PROPERTY(quint16 imageClarity READ imageClarity WRITE setImageClarity NOTIFY imageClarityChanged)
    
public:
    explicit SerialPortController(QObject *parent = nullptr);
    ~SerialPortController();
    
    // Property getters
    QStringList availablePorts() const { return m_availablePorts; }
    QString currentPort() const { return m_currentPort; }
    bool isConnected() const { return m_isConnected; }
    quint8 targetModuleId() const { return m_targetModuleId; }
    QString workStatus() const { return m_workStatus; }
    QString selfCheckStatus() const { return m_selfCheckStatus; }
    QString focusMode() const { return m_focusMode; }
    QString brakeStatus() const { return m_brakeStatus; }
    qint16 currentFocusStep() const { return m_currentFocusStep; }
    qint16 motorTotalTravel() const { return m_motorTotalTravel; }
    qint32 baudRate() const { return m_baudRate; }
    int dataBits() const { return m_dataBits; }
    int parity() const { return m_parity; }
    int stopBits() const { return m_stopBits; }
    int flowControl() const { return m_flowControl; }
    quint16 imageClarity() const { return m_imageClarity; }
    
    // Property setters
    void setCurrentPort(const QString &port);
    void setTargetModuleId(quint8 id);
    void setBaudRate(qint32 baudRate);
    void setDataBits(int dataBits);
    void setParity(int parity);
    void setStopBits(int stopBits);
    void setFlowControl(int flowControl);
    void setImageClarity(quint16 clarity);
    
    // Invokable methods for QML
    Q_INVOKABLE void refreshPorts();
    Q_INVOKABLE bool openPort();
    Q_INVOKABLE void closePort();
    Q_INVOKABLE void sendManualFocusPlus(quint8 stepLevel);
    Q_INVOKABLE void sendManualFocusMinus(quint8 stepLevel);
    Q_INVOKABLE void sendSetFocusValue(quint16 focusValue);
    Q_INVOKABLE void sendBrake();
    Q_INVOKABLE void sendBrakeRelease();
    Q_INVOKABLE void sendAutoFocus(quint16 imageClarity);
    Q_INVOKABLE void sendReset();
    Q_INVOKABLE void sendQuery();
    
    // Access to logger for QML
    CommunicationLogger* logger() const { return m_logger; }
    
    // Settings management
    void loadSettings();
    void saveSettings();
    
signals:
    void availablePortsChanged();
    void currentPortChanged();
    void isConnectedChanged();
    void targetModuleIdChanged();
    void workStatusChanged();
    void selfCheckStatusChanged();
    void focusModeChanged();
    void brakeStatusChanged();
    void currentFocusStepChanged();
    void motorTotalTravelChanged();
    void baudRateChanged();
    void dataBitsChanged();
    void parityChanged();
    void stopBitsChanged();
    void flowControlChanged();
    void imageClarityChanged();
    void errorOccurred(const QString &error);
    
private slots:
    void handleReadyRead();
    void handleError(QSerialPort::SerialPortError error);
    void handleFrameReceived(quint8 sourceId, quint8 command, quint8 workStatus,
                            qint16 currentStep, qint16 totalTravel);
    void handleFrameError(const QString &error);
    void handleResponseTimeout();
    
private:
    void sendCommand(quint8 command, const QByteArray &params);
    void updateConnectionState(bool connected);
    
    QSerialPort *m_serialPort;
    ProtocolHandler *m_protocolHandler;
    CommunicationLogger *m_logger;
    QTimer *m_responseTimer;
    
    QStringList m_availablePorts;
    QString m_currentPort;
    bool m_isConnected;
    quint8 m_targetModuleId;
    quint8 m_frameCounter;
    
    // Status fields
    QString m_workStatus;
    QString m_selfCheckStatus;
    QString m_focusMode;
    QString m_brakeStatus;
    qint16 m_currentFocusStep;
    qint16 m_motorTotalTravel;
    
    // Serial port configuration
    qint32 m_baudRate;
    int m_dataBits;
    int m_parity;
    int m_stopBits;
    int m_flowControl;
    
    // Image clarity (0-10000, representing 0.00-100.00)
    quint16 m_imageClarity;
};

#endif // SERIALPORTCONTROLLER_H
